package singleton;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

/**
 * @author liouwb
 * 单例模式 双重检查锁
 */
public class SingletonDoubleCheckLockTest {
    public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        // 懒汉式 双重检查锁
        SingletonLazyDoubleLock lazyDoubleLock = SingletonLazyDoubleLock.getInstance();
        SingletonLazyDoubleLock lazyDoubleLock1 = SingletonLazyDoubleLock.getInstance();

        // 通过反射实例
        Class<SingletonLazyDoubleLock> lazyClass = SingletonLazyDoubleLock.class;
        Constructor<SingletonLazyDoubleLock> constructor = lazyClass.getDeclaredConstructor();

        constructor.setAccessible(true);
        SingletonLazyDoubleLock lazyDoubleLock2 = constructor.newInstance();

        // 验证单例是否全局只有一个实例
        System.out.println("正常获取的实例比较：" + (lazyDoubleLock == lazyDoubleLock1));
        // 反射获取与正常获取对比
        System.out.println("正常获取的实例比较：" + (lazyDoubleLock == lazyDoubleLock2));

        // 输出相应对象
        System.out.println("lazyDoubleLock ：" + lazyDoubleLock);
        System.out.println("lazyDoubleLock1：" + lazyDoubleLock1);
        System.out.println("lazyDoubleLock2：" + lazyDoubleLock2);
    }

    /**
     * 懒汉式 双重加锁
     */
    static class SingletonLazyDoubleLock {
        //
        public static SingletonLazyDoubleLock instance;

        // 私有构造函数
        private SingletonLazyDoubleLock() {
        }

        public static synchronized SingletonLazyDoubleLock getInstance() {
            if (instance == null) {
                synchronized (SingletonLazyDoubleLock.class) {
                    if (instance == null) {
                        instance = new SingletonLazyDoubleLock();
                    }
                }
            }

            return instance;
        }
    }
}
